package sg.com.techstudio.tafep.validator;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.binding.message.MessageBuilder;
import org.springframework.binding.message.MessageContext;
import org.springframework.binding.validation.ValidationContext;
import org.springframework.stereotype.Component;

import sg.com.techstudio.tafep.obj.ParticipantObj;

@Component
public class ParticipantObjValidator extends BaseValidator {
	private static final Log log = LogFactory.getLog(ParticipantObjValidator.class);

	public void validateParticipantList(List<ParticipantObj> pList, ValidationContext context) {
		log.debug("validateParticipantList() entry");
		MessageContext messages = context.getMessageContext();
		
		if(pList==null)
			return;
		int i=0;
		for(ParticipantObj p: pList) {
			if(StringUtils.isBlank(p.getSalutation()) && StringUtils.isBlank(p.getSalutationOther()))
				addMessage(participantListFieldPath("salutation", i), "required.selectfield", messages);
			else if(!StringUtils.isBlank(p.getSalutation()))
				p.setSalutationOther(null); //clear salutation other
			validateEmptyString(p.getFirstName(), participantListFieldPath("firstName", i), messages);
			validateEmptyString(p.getLastName(), participantListFieldPath("lastName", i), messages);
			if(validateEmptyString(p.getBadgeName(), participantListFieldPath("badgeName", i), messages))
				if(p.getBadgeName().length()>20)
					p.setBadgeName(StringUtils.substring(p.getBadgeName(), 0, 20));
			validateEmptyString(p.getDesignation(), participantListFieldPath("designation", i), messages);
			if(validateEmptyString(p.getTelephone(), participantListFieldPath("telephone", i), messages))
				if(!PHONE_PATTERN.matcher(p.getTelephone()).matches())
					addMessage(participantListFieldPath("telephone", i), "invalid.telephone", messages);
//			if(validateEmptyString(p.getMobile(), participantListFieldPath("mobile", i), messages))
//				if(!PHONE_PATTERN.matcher(p.getMobile()).matches())
//					addMessage(participantListFieldPath("mobile", i), "invalid.mobile", messages);
			validateEmail(p.getEmail(), participantListFieldPath("email", i), messages);
			validateProgramme(p, i, messages);
			i++;
		}
	}
	
	public void validateParticipant(ParticipantObj p, ValidationContext context) {
		log.debug("validateParticipant() entry");
		MessageContext messages = context.getMessageContext();
		
		if(StringUtils.isBlank(p.getSalutation()) && StringUtils.isBlank(p.getSalutationOther()))
			messages.addMessage(new MessageBuilder().error().source("salutation")
				.code("required.field").build());
		else if(!StringUtils.isBlank(p.getSalutation()))
			p.setSalutationOther(null); //clear salutation other
		if(StringUtils.isBlank(p.getFirstName()))
			messages.addMessage(new MessageBuilder().error().source("firstName")
				.code("required.field").build());
		if(StringUtils.isBlank(p.getLastName()))
			messages.addMessage(new MessageBuilder().error().source("lastName")
				.code("required.field").build());
		if(StringUtils.isBlank(p.getBadgeName()))
			messages.addMessage(new MessageBuilder().error().source("badgeName")
				.code("required.field").build());
		if(StringUtils.isBlank(p.getDesignation()))
			messages.addMessage(new MessageBuilder().error().source("designation")
				.code("required.field").build());
		if(StringUtils.isBlank(p.getTelephone()))
			messages.addMessage(new MessageBuilder().error().source("telephone")
				.code("required.field").build());
		else if(!PHONE_PATTERN.matcher(p.getTelephone()).matches())
			messages.addMessage(new MessageBuilder().error().source("telephone")
					.code("invalid.telephone").build());
		if(!StringUtils.isBlank(p.getFax()) && !PHONE_PATTERN.matcher(p.getFax()).matches())
			messages.addMessage(new MessageBuilder().error().source("fax")
					.code("invalid.fax").build());
		if(!StringUtils.isBlank(p.getMobile()) && !PHONE_PATTERN.matcher(p.getMobile()).matches())
			messages.addMessage(new MessageBuilder().error().source("mobile")
					.code("invalid.mobile").build());
		validateEmail(p.getEmail(), "email", messages);
		if(!validateEmail(p.getAlternativeEmail(), "alternativeEmail", false, messages)
				&& !StringUtils.isBlank(p.getAlternativeEmail())
				&& StringUtils.equalsIgnoreCase(p.getEmail(), p.getAlternativeEmail()))
			messages.addMessage(new MessageBuilder().error().source("alternativeEmail")
					.code("same.email").build());
		validateProgramme(p, messages);
	}
	
	protected void validateProgramme(ParticipantObj p, int i, MessageContext messages) {
		log.debug("validateProgramme() entry");
		//none selected
		if(p.getPackageId()==null && !p.isPost1() && !p.isPost2())
			addMessage(participantListFieldPath("packageId", i), "required.programme", messages);
		else if(p.getPackageId()!=null) { //select any first 3 package
			if(p.getPackageId()==1) {
				if(p.getBreakoutChoice()[0]<=0) //|| p.getBreakoutChoice()[1]<=0 //remove validation on breakout 2
					addMessage(participantListFieldPath("breakoutChoice[0]", i), "required.breakout", messages);
			} else if(p.getPackageId()==3) {
				if(p.getBreakoutChoice()[2]<=0) //|| p.getBreakoutChoice()[1]<=0
					addMessage(participantListFieldPath("breakoutChoice[2]", i), "required.breakout", messages);
			}
		}
		
		/*
		if(!registerMainOrBreakout(p))
			messages.addMessage(new MessageBuilder().error().source(participantListFieldPath("main", i))
					.code("required.programme").build());
		else if(isBreakout(p.getBreakout1()) ^ isBreakout(p.getBreakout2())) //select both or none
			messages.addMessage(new MessageBuilder().error()
					.source(participantListFieldPath(isBreakout(p.getBreakout1())?"breakout2":"breakout1", i))
					.code("required.breakout").build());
		*/
		log.debug("validateProgramme() exit");
	}
	
	protected void validateProgramme(ParticipantObj p, MessageContext messages) {
		log.debug("validateProgramme() entry");
		if(!registerMainOrBreakout(p))
			messages.addMessage(new MessageBuilder().error().source("main")
					.code("required.programme").build());
		else if(isBreakout(p.getBreakout1()) ^ isBreakout(p.getBreakout2())) //select both or none
			messages.addMessage(new MessageBuilder().error().source(isBreakout(p.getBreakout1())?"breakout2":"breakout1")
					.code("required.breakout").build());
		log.debug("validateProgramme() exit");		
	}
	
	protected boolean registerMainOrBreakout(ParticipantObj p) {
		if(p==null)
			return false;
		return p.isMain() 
				|| isBreakout(p.getBreakout1()) || isBreakout(p.getBreakout2());
	}
	
	protected boolean isBreakout(Integer i) {
		return i!=null && i>0;
	}
	
	protected static final String PARTICIPANTLIST_PATH = "participantList";
	protected String participantListFieldPath(String fieldname, int i) {
		return PARTICIPANTLIST_PATH+"["+i+"]."+fieldname;
	}
}
